package com.oldking.controller;

import com.oldking.domain.VideoData;
import com.oldking.domain.VideoInfo;
import com.oldking.domain.VideoTask;
import com.oldking.utils.AlertMessageUtil;
import com.oldking.utils.CommonColorUtil;
import com.oldking.utils.CommonTimeUtil;
import com.oldking.utils.UUIDUtil;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.scene.media.Media;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaView;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.FileChooser;
import javafx.util.Duration;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import start.StarterClass;

import java.io.File;
import java.net.URL;
import java.util.List;
import java.util.ResourceBundle;

@Component
public class EditVideoController implements Initializable {


    private MediaPlayer mediaPlayer;
    private StarterClass application;

    @FXML
    private MediaView mediaView;
    @FXML
    private TableView taskView;
    @FXML
    private Slider volSlider;
    @FXML
    private Slider minSlider;
    @FXML
    private TextFlow currentTime;
    @FXML
    private TextFlow totalTime;

    @FXML
    private TableColumn taskName;
    @FXML
    private TableColumn startTime;
    @FXML
    private TableColumn endTime;
    @FXML
    private TableColumn opration;
    @FXML
    private Pane sliderPane;

    @FXML
    private void backVideoList(ActionEvent event) {
        VideoInfo videoInfo = VideoData.getVideoInfoByKey(VideoData.getKey());
        if (checkIfTimeUpdated(videoInfo)) {
            AlertMessageUtil.msg(Alert.AlertType.WARNING, "warning", "未设置完成,不能新增", "开始或者结束时间未设置完成");
            return;
        }
        mediaPlayer.stop();
        VideoData.setKey("");
        application.gotomain();
    }

    @FXML
    private void openvidFile(ActionEvent event) {
        FileChooser fileChooser = new FileChooser();
        FileChooser.ExtensionFilter filter = new FileChooser.ExtensionFilter("Select a File (*.mp4)", "*.mp4");
        fileChooser.getExtensionFilters().add(filter);
        File file = fileChooser.showOpenDialog(null);

    }

    @FXML
    private void playVid(ActionEvent event) {
        mediaPlayer.play();
        mediaPlayer.setRate(1);
    }

    @FXML
    private void pauseVid(ActionEvent event) {
        mediaPlayer.pause();
    }

    @FXML
    private void stopVid(ActionEvent event) {
        mediaPlayer.stop();
    }

    @FXML
    private void exitProg(ActionEvent event) {
        System.exit(0);
    }

    public void setApp(StarterClass application) {
        this.application = application;
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        String durationTime = VideoData.getVideoInfoByKey(VideoData.getKey()).getDuration();
        File file = new File(VideoData.getKey());
        String filePath = file.toURI().toString();
        if (filePath == null) {
            return;
        }
        Media media = new Media(filePath);
        mediaPlayer = new MediaPlayer(media);
        mediaView.setMediaPlayer(mediaPlayer);

        Text tt = new Text(" / " + durationTime);
        tt.setFont(new Font(15));
        totalTime.getChildren().add(tt);
        volSlider.setValue(mediaPlayer.getVolume() * 100);
        volSlider.valueProperty().addListener(new InvalidationListener() {
            @Override
            public void invalidated(Observable observable) {
                mediaPlayer.setVolume(volSlider.getValue() / 100);
            }
        });
        Text current = new Text();
        int t = CommonTimeUtil.Stringtime2Second(durationTime);
        minSlider.setMax(t);

        mediaPlayer.currentTimeProperty().addListener(new ChangeListener<Duration>() {
            @Override
            public void changed(ObservableValue<? extends Duration> observable, Duration oldValue, Duration newValue) {
                minSlider.setValue(newValue.toSeconds());
                VideoData.setCurrentTime((int) minSlider.getValue());
                long l = Math.round(minSlider.getValue());
                setCurrentByTime(l, current);

            }
        });
        addSliderMouseDragged(current);

        minSlider.setOnMouseMoved(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                if (!"HAND".equals(Cursor.HAND)) {
                    minSlider.setCursor(Cursor.HAND);
                }
            }
        });

        sliderPane.setOnMouseClicked(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                mediaPlayer.pause();

                long l = Math.round(minSlider.getValue());
                try {
                    mediaPlayer.seek(Duration.seconds(minSlider.getValue()));
                    VideoData.setCurrentTime((int) minSlider.getValue());
                    setCurrentByTime(l, current);
                } catch (Exception e) {

                }
            }
        });
        VideoInfo videoInfoByKey = VideoData.getVideoInfoByKey(VideoData.getKey());
        ObservableList<VideoTask> taskList = FXCollections.observableArrayList();
        taskList.addAll(videoInfoByKey.getVideotask());
        taskView.setItems(taskList);
        taskView.setEditable(true);
        initTableColumn();
        showAllRectlage(videoInfoByKey);

    }

    private void showAllRectlage(VideoInfo videoInfo) {
        ObservableList<VideoTask> taskList = FXCollections.observableArrayList();

        List<VideoTask> videotask = videoInfo.getVideotask();
        taskList.addAll(videotask);
        for (int i = 0; i < taskList.size(); i++) {
            VideoTask videoTask = taskList.get(i);
            int intStart = CommonTimeUtil.Stringtime2Second(videoTask.getStartTime().getText());
            int intEnd = CommonTimeUtil.Stringtime2Second(videoTask.getEndTime().getText());
            String durationTime = VideoData.getVideoInfoByKey(VideoData.getKey()).getDuration();
            int t = CommonTimeUtil.Stringtime2Second(durationTime);
            double vStart = (intStart * this.minSlider.getPrefWidth() / t);
            double vEnd = (intEnd * this.minSlider.getPrefWidth() / t);
            String id = String.valueOf(i + 1);
            addOneSliderRectangle(sliderPane, "startTimeBtn", id, vStart);
            addOneSliderRectangle(sliderPane, "endTimeBtn", id, vEnd);
        }
    }

    private void addSliderMouseDragged(Text current) {
        minSlider.setOnMouseDragged(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                long l = Math.round(minSlider.getValue());
                try {
                    mediaPlayer.seek(Duration.seconds(minSlider.getValue()));
                    VideoData.setCurrentTime((int) minSlider.getValue());
                    setCurrentByTime(l, current);
                } catch (Exception e) {

                }
            }
        });
    }


    private void setCurrentByTime(long l, Text current) {
        current.setFont(new Font(15));
        current.setText(CommonTimeUtil.secondToTime(l));
        if (currentTime.getChildren().size() == 0) {
            currentTime.getChildren().add(current);
        } else {
            currentTime.getChildren().set(0, current);
        }
    }


    public void addVideoTask(ActionEvent actionEvent) {
        sliderPane.setStyle("-fx-background-color: #66CCFF");
        addVideotask();
    }

    private void addVideotask() {
        ObservableList<VideoTask> items = taskView.getItems();
        ObservableList<VideoTask> taskList = FXCollections.observableArrayList();
        VideoInfo videoInfo = VideoData.getVideoInfoByKey(VideoData.getKey());
        if (checkIfTimeUpdated(videoInfo)) {
            AlertMessageUtil.msg(Alert.AlertType.WARNING, "warning", "未设置完成,不能新增", "开始或者结束时间未设置完成");
            return;
        }

        VideoTask videoTask = new VideoTask();
        videoTask.setId(UUIDUtil.getUUID());
        videoTask.setParentId(videoInfo.getId());
        videoTask.setTaskName(videoInfo.getFileName() + (items.size() + 1));

        Button startTimeBtn = new Button("设置");
        startTimeBtn.setId(String.valueOf(taskView.getItems().size() + 1));

        startTimeBtn.setOnMouseClicked(ActionEvent -> {
            boolean contains = sliderPane.getStyle().contains("#66CCFF");
            if (!contains) {
                return;
            }
            String durationTime = VideoData.getVideoInfoByKey(VideoData.getKey()).getDuration();
            int t = CommonTimeUtil.Stringtime2Second(durationTime);
            double v = (minSlider.getValue() / t) * minSlider.getWidth();
            String id = ((Node) ActionEvent.getSource()).getId();
            sliderPane.setStyle("-fx-background-color: #66CCFF");
            addOneSliderRectangle(sliderPane, "startTimeBtn", id, v);
            setTimeValue(ActionEvent, "startTime");

        });
        videoTask.setStartTime(startTimeBtn);

        Button endTimeBtn = new Button("设置");
        endTimeBtn.setId(String.valueOf(taskView.getItems().size() + 1));
        endTimeBtn.setOnMouseClicked(ActionEvent -> {
            boolean contains = sliderPane.getStyle().contains("#66CCFF");
            if (!contains) {
                return;
            }
            String id = ((Node) ActionEvent.getSource()).getId();
            ObservableList it = taskView.getItems();
            VideoTask vt = (VideoTask) it.get(Integer.valueOf(id) - 1);
            int i = CommonTimeUtil.Stringtime2Second(vt.getStartTime().getText());
            if (i >= minSlider.getValue()) {
                AlertMessageUtil.msg(Alert.AlertType.ERROR, "error", "结束时间不能小于开始时间", "");
                return;
            }
            String durationTime = VideoData.getVideoInfoByKey(VideoData.getKey()).getDuration();
            int t = CommonTimeUtil.Stringtime2Second(durationTime);
            double v = (minSlider.getValue() / t) * minSlider.getWidth();
            addOneSliderRectangle(sliderPane, "endTimeBtn", id, v);
            setTimeValue(ActionEvent, "endTime");
        });
        videoTask.setEndTime(endTimeBtn);


        taskList.add(videoTask);
        initTableColumn();
        items.addAll(taskList);
        taskView.setItems(items);
        taskView.setEditable(true);
        taskName.setCellFactory(TextFieldTableCell.forTableColumn());
        videoInfo.getVideotask().add(videoTask);

    }

    private boolean checkIfTimeUpdated(VideoInfo videoInfo) {
        List<VideoTask> videotaskList = videoInfo.getVideotask();
        for (VideoTask videoTask : videotaskList) {
            String StartText = videoTask.getStartTime().getText();
            String endText = videoTask.getEndTime().getText();
            if ("设置".equals(StartText) || "设置".equals(endText)) {
                return true;
            }
        }
        return false;
    }

    private void setTimeValue(MouseEvent actionEvent, String type) {
        String id = ((Node) actionEvent.getSource()).getId();
        ObservableList items = taskView.getItems();
        VideoTask v = (VideoTask) items.get(Integer.valueOf(id) - 1);
        long l = new Double(minSlider.getValue()).longValue();
        if ("startTime".equals(type)) {
            v.getStartTime().setText(CommonTimeUtil.secondToTime(l));
        } else if ("endTime".equals(type)) {
            v.getEndTime().setText(CommonTimeUtil.secondToTime(l));
        }

    }

    private void addOneSliderRectangle(Pane sliderPane, String btnTypleText, String id, double v) {

        Rectangle rectangleStart = createSliderNewRectangle(CommonColorUtil.getColorByKey(Integer.valueOf(id)), v, btnTypleText + id, id);
        ObservableList<Node> children = sliderPane.getChildren();
        if (children.size() == 1) {
            sliderPane.getChildren().add(rectangleStart);
            return;
        }
        boolean flag = false;
        for (int i = 1; i < children.size(); i++) {
            if (ObjectUtils.isEmpty(children.get(i).getId())) {
                continue;
            }
            if (children.get(i).getId().contains(btnTypleText + id)) {
                flag = true;
                break;
            }
        }
        if (flag) {
            for (int i = 1; i < children.size(); i++) {
                if (ObjectUtils.isEmpty(children.get(i).getId())) {
                    continue;
                }
                Rectangle r = (Rectangle) children.get(i);

                if (r.getId().equals(btnTypleText + id)) {
                    sliderPane.getChildren().set(i, rectangleStart);
                    return;
                }
            }
        } else {
            sliderPane.getChildren().add(rectangleStart);
        }
    }


    private Rectangle createSliderNewRectangle(String color, double X, String nodeId, String id) {
        Rectangle rectangle = new Rectangle();
        rectangle.setId(nodeId);
        rectangle.setFill(Paint.valueOf(color));
        rectangle.setX(X + 2.5);
        rectangle.setWidth(2.0);
        rectangle.setHeight(23.0);
        return rectangle;
    }

    private void initTableColumn() {
        taskName.setCellValueFactory(new PropertyValueFactory("taskName"));
        startTime.setCellValueFactory(new PropertyValueFactory("startTime"));
        endTime.setCellValueFactory(new PropertyValueFactory("endTime"));
        //     opration.setCellValueFactory(new PropertyValueFactory("opration"));
    }

    public void delVideoTask(ActionEvent actionEvent) {
        ObservableList<VideoTask> videoTaskList = taskView.getItems();
        if (videoTaskList.size() == 0) {
            return;
        }
        VideoTask task = videoTaskList.get(videoTaskList.size() - 1);
        videoTaskList.remove(task);
        taskView.setItems(videoTaskList);
        String id = String.valueOf(videoTaskList.size() + 1);
        deleteVideoOne(id, sliderPane);
        sliderPane.setStyle("-fx-background-color: #ffffff");
    }

    private void deleteVideoOne(String id, Pane sliderPane) {
        VideoInfo videoInfo = VideoData.getVideoInfoByKey(VideoData.getKey());
        List<VideoTask> videotaskList = videoInfo.getVideotask();
        videoInfo.getVideotask().remove(videotaskList.get(videotaskList.size() - 1));

        ObservableList<Node> children = sliderPane.getChildren();
        boolean flag = false;
        for (int i = 1; i < children.size(); i++) {
            if (ObjectUtils.isEmpty(children.get(i).getId())) {
                continue;
            }
            if (children.get(i).getId().contains(id)) {
                flag = true;
                break;
            }
        }
        if (flag) {
            for (int i = 1; i < children.size(); i++) {
                if (ObjectUtils.isEmpty(children.get(i).getId())) {
                    continue;
                }
                Rectangle r = (Rectangle) children.get(i);

                if (r.getId().contains(id)) {
                    sliderPane.getChildren().remove(i);
                    i--;
                }
            }
        }
    }

    private void deleteAllRectangle(Pane sliderPane) {
        ObservableList<Node> children = sliderPane.getChildren();

        for (int i = 1; i < children.size(); i++) {
            if (ObjectUtils.isEmpty(children.get(i).getId())) {
                continue;
            }
            Rectangle r = (Rectangle) children.get(i);
            sliderPane.getChildren().remove(i);
            i--;
        }
    }

    public void submitEdit(ActionEvent actionEvent) {
        VideoInfo videoInfo = VideoData.getVideoInfoByKey(VideoData.getKey());
        if (checkIfTimeUpdated(videoInfo)) {
            AlertMessageUtil.msg(Alert.AlertType.WARNING, "warning", "未设置完成,不能新增", "开始或者结束时间未设置完成");
            return;
        }
        sliderPane.setStyle("-fx-background-color: #ffffff");
    }

    public void submitVideoList(ActionEvent actionEvent) {
        VideoInfo videoInfo = VideoData.getVideoInfoByKey(VideoData.getKey());
        if (checkIfTimeUpdated(videoInfo)) {
            AlertMessageUtil.msg(Alert.AlertType.WARNING, "warning", "未设置完成,不能新增", "开始或者结束时间未设置完成");
            return;
        }

        mediaPlayer.stop();
        application.gotoaudiomanage("");
    }
}